package com.auoem.radio.ui.ptt;

import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.ViewModelProvider;

import com.auctus.am.developer.AuHelper;
import com.auctus.am.framework.constants.AmConstants;
import com.auctus.am.framework.entity.CallStatus;
import com.auctus.am.framework.entity.ChannelInf;
import com.auctus.am.framework.entity.Contact;
import com.auctus.am.framework.enums.ApiStatusEnum;
import com.auctus.am.framework.enums.PttStatus;
import com.auctus.am.framework.gpio.RootCmdManager;
import com.auctus.am.framework.imp.RadioData;
import com.auctus.am.framework.imp.RadioManager;
import com.auctus.am.framework.interfaces.ApiCallback;
import com.auctus.am.framework.interfaces.ComCallback;
import com.auctus.am.framework.interfaces.IChannelSwitchListener;
import com.auctus.am.framework.interfaces.IPttListener;
import com.auctus.am.framework.picker.IIntPickDataWrap;
import com.auctus.am.framework.picker.RadioPickData;
import com.auctus.am.framework.tasks.RadioTaskManager;
import com.auctus.am.framework.tasks.SwitchChannelTask;
import com.auctus.am.framework.utils.LogM;
import com.auoem.radio.MainViewModel;
import com.auoem.radio.R;
import com.auoem.radio.base.AuConstants;
import com.auoem.radio.base.BaseFragment;
import com.auoem.radio.base.OemApplication;
import com.auoem.radio.common.custview.SeekProgressBarExt;
import com.auoem.radio.common.custview.wheel.SimplePickerDialog;
import com.auoem.radio.databinding.FragmentPttBinding;
import com.auoem.radio.ui.other.TestSysInfActivity;

import java.io.IOException;

/**
 *  20240418  恢复mic控制监听
 */
public class PttFragment extends BaseFragment implements IPttListener, IChannelSwitchListener, View.OnClickListener {

    private static final String TAG = "PttFragment";

    FragmentPttBinding mBinding;
    private MainViewModel mainViewModel;

    private int curVolume;

    private RadioData mRadioData;

    private ChannelInf curChannel;
    private SimplePickerDialog mSelectDialog;

    private IIntPickDataWrap pickDataCh;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        mBinding = FragmentPttBinding.inflate(inflater);
        ViewModelProvider.AndroidViewModelFactory instance = ViewModelProvider.AndroidViewModelFactory.getInstance(OemApplication.getApplication());
        mainViewModel = new ViewModelProvider(requireActivity(), instance).get(MainViewModel.class);
        initData();
        initView();
        updateOther();
        updateVolOnShow();
        LogM.d(TAG, "onCreate curChannel isNUll: " + (curChannel == null));
        if (curChannel == null) {
            mRadioData.setCurChannel(mRadioData.getChannelOnIndex(mRadioData.getLastChId()));
            switchCurChange(mRadioData.getLastChId());
        } else {
            updateChInf();
        }

        return mBinding.getRoot();
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    private void initView() {
//        requireActivity().getActionBar().setTitle("PttFragment");
        mBinding.ivPtt.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        ptt(true);
                        updatePttStatus(PttStatus.Snd);
                        return true;
                    case MotionEvent.ACTION_UP:
                        ptt(false);
                        updatePttStatus(PttStatus.Wait);
                        return false;
                }
                return false;
            }
        });
        mBinding.sbVol.setProgress(getVolProgress());
        mBinding.sbVol.setComCallback(new ComCallback<Float>() {
            @Override
            public void onCallback(Float aFloat, int code, String inf) {
                int volP = (int) ((float) AmConstants.MAX_VOLUME * aFloat);
                if (code == SeekProgressBarExt.PICK_PROGRESS) {
                    setCurVolume(volP);
                }
                if (volP != curVolume) {
                    curVolume = volP;
                    updateVol(true, curVolume);
                }
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!AmConstants.IS_DEBUG_BEFORE_DEV) {
            /*Step-4 监听A6状态*/
            /*Step-4.1设置PTT状态监听*/
            RadioManager.getInstance().getPttControl().setPttListener(this);
            /*Step-4.2设置信道切换监听*/
            RadioManager.getInstance().getRadioData().setChannelSwitchListener(this);
        }
        //更新各项状态
        curChannel = RadioManager.getInstance().getRadioData().getCurChannel();
        updateChPicker();
        updateChInf();
        updatePower();
        updateCallStatus(RadioManager.getInstance().getPttControl().getCallStatus());

    }

    @Override
    public void onPause() {
        updateOnPause();
        if (!AmConstants.IS_DEBUG_BEFORE_DEV) {
            RadioManager.getInstance().getPttControl().setPttListener(null);
            RadioManager.getInstance().getRadioData().setChannelSwitchListener(null);
            ptt(false);
        }
        super.onPause();
    }

    @Override
    public void onClick(View v) {
        if (v == mBinding.ivPre) {
            changeCh(false);
        } else if (v == mBinding.ivNext) {
            changeCh(true);
        } else if (v == mBinding.tvChannelId) {
            showChSelect();
        }
    }

    private void initData() {
//        if (AmConstants.IS_DEBUG_BEFORE_DEV) {
//            return;
//        }
        mRadioData = RadioManager.getInstance().getRadioData();
        curChannel = mRadioData.getCurChannel();
        curVolume = mRadioData.getCurVolume();
        LogM.d(TAG, "volume cur: %d", curVolume);
    }

    private void updateChPicker() {
        pickDataCh = RadioPickData.getInstance().getChPick(mRadioData.getChannelList());
    }

    private float getVolProgress() {
        return (float) curVolume / (float) AmConstants.MAX_VOLUME;
    }

    private void changeCh(boolean isNext) {
//        int nChId = mRadioData.getCirChId(isNext);
        int nChId = mRadioData.selCirChId(isNext);
        switchCurChange(nChId);
    }

    private void switchCurChange(int index) {
        if (AmConstants.IS_DEBUG_BEFORE_DEV) {
            return;
        }
        curChannel = mRadioData.getChannelOnIndex(index);
        /*Step-5.1切换信道后更新当前状态*/
        updateChInf();
        showProgress(R.string.hl_ptt_switch_ch_progress);
        /*Step-5 切换信道，第一次进入App通常切换到上次的信道*/
        RadioTaskManager.getInstance().startSwitchChannelTask(mRadioData, index, new ComCallback<Boolean>() {
            @Override
            public void onCallback(Boolean isSucc, int code, String inf) {
                LogM.d(TAG, "setCurChange: index: %d  code: %d  msg: %s", index, code, inf);
                if (isSucc) {
                    toastResultUI(R.string.hl_ptt_switch_ch_complete_final);
                } else if (code == SwitchChannelTask.CODE_STOP) {
                    //主动停止的任务，不处理
                } else if (code >= 2) {
                    toastResultUI(R.string.hl_ptt_switch_ch_complete_half);
                } else {
                    toastResultUI(R.string.am_common_exe_failure);
                }
            }
        });
    }

    private void showChSelect() {
        showSingleSelect(pickDataCh, new SimplePickerDialog.OnPickListener() {
            @Override
            public void onPicked(int sel1, int v1) {
                switchCurChange(v1);
            }
        });
    }

    public void showSingleSelect(IIntPickDataWrap intPickDataWrap, SimplePickerDialog.OnPickListener onPickListener) {
        if (mSelectDialog == null) {
            mSelectDialog = new SimplePickerDialog(getActivity(), intPickDataWrap, 0, onPickListener, null);
        } else {
            mSelectDialog.update(intPickDataWrap, SimplePickerDialog.INVALID, onPickListener, null);
        }
        mSelectDialog.show();
    }


    private void updateVol(boolean isFromProgress, int vol) {
        float percent = (float) vol / (float) AmConstants.MAX_VOLUME;
        if (!isFromProgress) {
            mBinding.sbVol.setProgress(percent);
        }
        mBinding.tvVolV.setText(vol + "");
    }

    private void updateVolOnShow() {
        mBinding.sbVol.setProgress(getVolProgress());
        mBinding.tvVolV.setText(curVolume + "");
    }

    @UiThread
    private void updateChInf() {
        if (curChannel == null) {
            return;
        }
        updateChType(curChannel.isDigModel);
        updateCh(curChannel.channelId);
        updateCt();
        mBinding.setChInf(curChannel);
        updatePttStatus(PttStatus.Wait);
    }

    @UiThread
    private void updateCh(int chId) {
        mBinding.tvChannelId.setText((chId + 1) + "");
    }

    @UiThread
    private void updateCt() {
        try {
            requireActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Contact contact = mRadioData.getContactOnTag(curChannel.ctTag);
                    mBinding.tvCtV.setText(contact == null ? "-" : contact.name);
                }
            });
        } catch (IllegalStateException e) {
            System.out.println("requireActivity illegal");
        }
    }

    private void updateChType(boolean isDig) {
        try {
            requireActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mainViewModel.updateTitle(isDig ? "数字对讲" : "模拟对讲");
                    mBinding.llDig.setVisibility(isDig ? View.VISIBLE : View.GONE);
                    mBinding.tvColorK.setVisibility(isDig ? View.VISIBLE : View.GONE);
                    mBinding.tvColorV.setVisibility(isDig ? View.VISIBLE : View.GONE);
                }
            });
        } catch (IllegalStateException e) {
            System.out.println("requireActivity illegal");
        }
    }


    private void updateCallStatus(CallStatus callStatus) {
        if (callStatus == null) {
            return;
        }
        try {
            requireActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    LogM.d(TAG, "updateCallStatus: " + callStatus.pttStatus);
                    updatePttStatus(callStatus.pttStatus);
                    mBinding.tvInCall.setText(callStatus.callInf);
                }
            });
        } catch (IllegalStateException e) {
            System.out.println("requireActivity illegal");
        }
    }

    private void updateOther() {
        //高低功率
    }

    private void ptt(boolean isOn) {
//        OemApplication.getApplication().startMic(isOn);
        RadioManager.getInstance().getPttControl().pttSnd(isOn);
    }

    private void updatePttStatus(PttStatus pttStatus) {
        LogM.d(TAG, "onCallStatus: " + pttStatus);
        switch (pttStatus) {
            case Wait:
                mBinding.ivPtt.setImageResource(R.mipmap.hl_ptt_btn_normal);
                break;
            case Rev:
                mBinding.ivPtt.setImageResource(R.mipmap.hl_ptt_btn_rev);
                break;
            case Snd:
                mBinding.ivPtt.setImageResource(R.mipmap.hl_ptt_btn_snd);
                break;
        }
    }

    private void updateOnPause() {
        updatePttStatus(PttStatus.Wait);
        mBinding.tvInCall.setText("");
    }

    private void updatePower() {
        mBinding.tvPowerV.setText(mRadioData.getRadioBaseInf().powerLv == 1 ? "高" : "低");
    }

    private void setCurVolume(int volumeNew) {
        curVolume = volumeNew;
        mRadioData.setCurVolume(curVolume);
        showProgress(R.string.am_common_exe_ing);
        AuHelper.getInstance().getApi().setVolume(volumeNew, new ApiCallback() {
            @Override
            public void onResponse(ApiStatusEnum status, Object result, String msg) {
                toastResultUI(status);
            }
        });
        LogM.d(TAG, "setVol: %d", volumeNew);
    }

    private void goTest() {
        Intent intent = new Intent(getActivity(), TestSysInfActivity.class);
        startActivity(intent);
    }


    @Override
    public void onCallStatus(CallStatus callStatus) {
        /*Step-6 根据PTT状态更新UI*/
        LogM.d(TAG, "onCallStatus: " + callStatus.pttStatus);
        //这部分留在服务中进行处理试试
        ctlGpioOnStatus(callStatus);
        updateCallStatus(callStatus);
    }


    /*Step-6.1 手工根据PTT状态控制GPIO*/
    private void ctlGpioOnStatus(CallStatus callStatus) {
        switch (callStatus.pttStatus) {
            case Wait:
                try {
                    OemApplication.getApplication().getDevCtrlHorn1().PowerOffDevice();
                    OemApplication.getApplication().getDevCtrlHorn3().PowerOffDevice();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                //根据之前的状态控制GPIO，或者两者都关闭
                RootCmdManager.getInstance().enablePath(AuConstants.AM_PATH_POWER_TX, false);
                RootCmdManager.getInstance().enablePath(AuConstants.AM_PATH_POWER_MIC, false);
                break;
            case Rev:
                try {
                    OemApplication.getApplication().getDevCtrlHorn3().PowerOnDevice();
                    OemApplication.getApplication().getDevCtrlHorn1().PowerOnDevice();
                    OemApplication.getApplication().getDevCtrlHorn1().PowerOffDevice();
                    OemApplication.getApplication().getDevCtrlHorn1().PowerOnDevice();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                RootCmdManager.getInstance().enablePath(AuConstants.AM_PATH_POWER_TX, true);
                break;
            case Snd:
                try {
                    OemApplication.getApplication().getDevCtrlHorn1().PowerOffDevice();
                    OemApplication.getApplication().getDevCtrlHorn3().PowerOffDevice();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                RootCmdManager.getInstance().enablePath(AuConstants.AM_PATH_POWER_MIC, true);
                break;
        }
    }

    @Override
    public void onChangeSwitch(ChannelInf channelInf, int id) {
        curChannel = channelInf;
        updateChInf();
    }
}
